package com.zshan.clinic.cms.framework.config.druid;

import com.alibaba.druid.pool.DruidDataSource;
import com.zshan.clinic.common.util.string.StringUtil;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 提供基础数据源功能
 */
@Configuration
@CommonsLog
public abstract class AbstractDruidDBConfig {

    @Autowired
    private DruidDbProperties druidDbProperties;

//
    public DruidDataSource createDataSource(String url, String username, String password) {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(url);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(druidDbProperties.getDriverClassName());
        datasource.setDbType(druidDbProperties.getDbType());
        datasource.setInitialSize(druidDbProperties.getInitialSize()); //初始化连接大小
        datasource.setMinIdle(druidDbProperties.getMinIdle());//连接池最大使用连接数量
        datasource.setMaxActive(druidDbProperties.getMaxActive());//连接池最小空闲
        datasource.setMaxWait(druidDbProperties.getMaxWait());//获取连接最大等待时间
        datasource.setTimeBetweenEvictionRunsMillis(druidDbProperties.getTimeBetweenEvictionRunsMillis());//配置间隔多久才进行一次检测
        datasource.setMinEvictableIdleTimeMillis(druidDbProperties.getMinEvictableIdleTimeMillis());//配置一个连接在池中最小生存的时间
        datasource.setValidationQuery(druidDbProperties.getValidationQuery());
        datasource.setTestWhileIdle(druidDbProperties.isTestWhileIdle());
        datasource.setTestOnBorrow(druidDbProperties.isTestOnBorrow());
        datasource.setTestOnReturn(druidDbProperties.isTestOnReturn());
        datasource.setPoolPreparedStatements(druidDbProperties.isPoolPreparedStatements());
        datasource.setMaxPoolPreparedStatementPerConnectionSize(druidDbProperties.getMaxPoolPreparedStatementPerConnectionSize());
        try {
            datasource.setFilters(druidDbProperties.getFilters());
        } catch (SQLException e) {
            log.error("druid configuration initialization filter", e);
        }
        datasource.setConnectionProperties(druidDbProperties.getConnectionProperties());
        return datasource;
    }


    /**
     * 加载mybatis xml配置文件
     *
     * @param dataSource      数据源
     * @param mapperLocations 自定义xml配置路径
     * @return
     * @throws Exception
     */
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource, String [] mapperLocations,String typeAliasesPackage) throws Exception {
        return createSqlSessionFactory(dataSource, mapperLocations,typeAliasesPackage);
    }

    private SqlSessionFactory createSqlSessionFactory(DataSource dataSource, String [] mapperLocations,String typeAliasesPackage) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        // 合并所有路径下的 Resource
        List<Resource> resourceList = new ArrayList<>();
        for (String location : mapperLocations) {
            Resource [] resources = resolver.getResources(location);
            resourceList.addAll(Arrays.asList(resources));
        }
        sqlSessionFactoryBean.setMapperLocations(resourceList.toArray(new Resource[0]));
        if(StringUtil.isNotBlank(typeAliasesPackage)){
            sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        }
        return sqlSessionFactoryBean.getObject();
    }

}
